#include "HixlEventLoop.h"
#include "HixlCsClient.h"
#include "adapter_hccp_common.h"   // 声明 hrtRaCreateEventHandle 等

namespace hixl {
    HixlEventLoop::HixlEventLoop() {
        // 创建 epoll event handle
        ::HcclResult ret = hrtRaCreateEventHandle(eventHandle_);
        if (ret != 0) {
            eventHandle_ = -1;
        }

        // 自动启动事件线程（等待 epoll 事件）
        if (eventHandle_ >= 0) {
            running_.store(true);
            loopThread_ = std::thread(&HixlEventLoop::Run, this, 100); // 100ms 超时
        }
    }

    HixlEventLoop::~HixlEventLoop() {
        running_.store(false);
        if (loopThread_.joinable()) {
            loopThread_.join();
        }

        if (eventHandle_ >= 0) {
            (void) hrtRaDestroyEventHandle(eventHandle_);
            eventHandle_ = -1;
        }
    }

    hccl::HcclResult HixlEventLoop::AddClient(hccl::FdHandle fd, HixlCsClient *client) {
        if (eventHandle_ < 0 || fd == nullptr || client == nullptr) {
            return hccl::HcclResult::E_PARA;
        } {
            std::lock_guard<std::mutex> lk(mapMutex_);
            clients_[fd] = client;
        }

        // 关心读写事件（RA_EPOLLIN / RA_EPOLLOUT 定义在 hccl_network.h 或相关头文件中）
        HcclEpollEvent evt = static_cast<HcclEpollEvent>(RA_EPOLLIN | RA_EPOLLOUT);

        ::HcclResult ret = hrtRaCtlEventHandle(eventHandle_, fd, EPOLLCTLADD, evt);
        if (ret != 0) {
            std::lock_guard<std::mutex> lk(mapMutex_);
            clients_.erase(fd);
            return hccl::HcclResult::E_PARA;
        }

        return hccl::HcclResult::SUCCESS;
    }

    hccl::HcclResult HixlEventLoop::DelClient(hccl::FdHandle fd) {
        if (eventHandle_ < 0 || fd == nullptr) {
            return hccl::HcclResult::E_PARA;
        } {
            std::lock_guard<std::mutex> lk(mapMutex_);
            clients_.erase(fd);
        }

        // 从 epoll 移除
        HcclEpollEvent evt = RA_EPOLLINVALD;
        (void) hrtRaCtlEventHandle(eventHandle_, fd, EPOLLCTLDEL, evt);

        return hccl::HcclResult::SUCCESS;
    }

    void HixlEventLoop::Run(int waitTimeoutMs) {
        if (eventHandle_ < 0) {
            return;
        }

        const u32 MAX_EVENTS = 64;
        std::vector<SocketEventInfo> eventInfos(MAX_EVENTS);

        while (running_.load()) {
            u32 eventsNum = 0;
            ::HcclResult ret = hrtRaWaitEventHandle(
                eventHandle_,
                eventInfos,
                waitTimeoutMs,
                MAX_EVENTS,
                eventsNum);
            if (ret != 0) {
                continue; // 可加日志
            }

            for (u32 i = 0; i < eventsNum; ++i) {
                hccl::FdHandle fd = eventInfos[i].fdHandle;

                HixlCsClient *client = nullptr; {
                    std::lock_guard<std::mutex> lk(mapMutex_);
                    auto it = clients_.find(fd);
                    if (it == clients_.end()) {
                        continue;
                    }
                    client = it->second;
                }

                if (client == nullptr) {
                    continue;
                }

                // 当前握手阶段不需要区分读/写事件，只要有事件就尝试推进一次
                (void) client->OnSocketEvent(fd);
            }
        }
    }
} // namespace hixl
